package com.hotel.project.gateway.apollo;

import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * 网关路由器监听
 *
 * @author: peng.ni
 * @date: 2022/04/13
 */
@Component
@Slf4j
public class GatewayPropertyRefresher implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    private GatewayProperties gatewayProperties;
    private DynamicRouteServiceImpl dynamicRouteService;

    public GatewayPropertyRefresher(DynamicRouteServiceImpl dynamicRouteService, GatewayProperties gatewayProperties) {
        this.dynamicRouteService = dynamicRouteService;
        this.gatewayProperties = gatewayProperties;
    }

    /**
     * 监听路由修改
     * `
     *
     * @param changeEvent 改变事件
     */
    @ApolloConfigChangeListener(interestedKeyPrefixes = {"spring.cloud.gateway.routes"})
    public void onChange(ConfigChangeEvent changeEvent) {
        boolean gatewayPropertiesChanged = false;
        for (String changedKey : changeEvent.changedKeys()) {
            if (changedKey.startsWith("spring.cloud.gateway.routes")) {
                gatewayPropertiesChanged = true;
                break;
            }
        }
        //TODO 判断是增加/删除操作
        if (gatewayPropertiesChanged) {
            GatewayPropertRefresher(changeEvent);
        }
    }

    /**
     * 刷新路由信息
     *
     * @param changeEvent 修改事件
     */
    private void GatewayPropertRefresher(ConfigChangeEvent changeEvent) {
        log.info("Refreshing gateway properties");
        // 更新配置
        this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
        // 更新路由
        gatewayProperties.getRoutes().forEach(dynamicRouteService::update);
        log.info("gateway properties refreshed");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
